use axum::{
    Router,
    extract::Path,
    http::StatusCode,
    response::{Html, Json},
    routing::{get, post},
};
use serde::{Deserialize, Serialize};
use tower::ServiceBuilder;
use tower_http::cors::CorsLayer;

#[derive(Serialize, Deserialize)]
struct User {
    id: u32,
    name: String,
    email: String,
}

#[derive(Serialize)]
struct ApiResponse<T> {
    success: bool,
    data: Option<T>,
    message: String,
}

/// Root route handler
/// Returns a welcome message
async fn root() -> Html<&'static str> {
    Html("<h1>Axum Web Server</h1><p>Welcome to Rust Axum Framework!</p>")
}

/// Health check route handler
/// Returns a success message if the server is healthy
async fn health() -> Json<ApiResponse<String>> {
    Json(ApiResponse {
        success: true,
        data: Some("OK".to_string()),
        message: "Server is healthy".to_string(),
    })
}

/// User route handler
/// Returns a user by ID
async fn get_user(Path(user_id): Path<u32>) -> Result<Json<ApiResponse<User>>, StatusCode> {
    let user = User {
        id: user_id,
        name: format!("User {}", user_id),
        email: format!("user{}@example.com", user_id),
    };

    Ok(Json(ApiResponse {
        success: true,
        data: Some(user),
        message: "User found".to_string(),
    }))
}

/// User creation route handler
/// Creates a new user
async fn create_user(Json(payload): Json<User>) -> Json<ApiResponse<User>> {
    Json(ApiResponse {
        success: true,
        data: Some(payload),
        message: "User created successfully".to_string(),
    })
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(root))
        .route("/health", get(health))
        .route("/users/{id}", get(get_user))
        .route("/users", post(create_user))
        .layer(ServiceBuilder::new().layer(CorsLayer::permissive()));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .expect("Failed to bind to port 3000");

    println!("📋 Available endpoints:");
    println!("  GET  /           - Welcome page");
    println!("  GET  /health     - Health check");
    println!("  GET  /users/{{id}}  - Get user by ID");
    println!("  POST /users      - Create new user");
    println!("🚀 Server running on http://localhost:3000");

    axum::serve(listener, app)
        .await
        .expect("Failed to start server");
}
